<?php
/*
 * @Description: 腾讯短信类
 * @Author: QianLong
 * @Date: 2019-09-27 16:34:02
 * @LastEditors    : QianLong
 * @LastEditTime   : 2023-03-03 10:28:15
 */

namespace App\Service\Sms;

use App\Exception\ApiException;
use App\Service\Captcha\TencBase;

class TenSms
{
    /**
     * 接口请求
     */
    public function sendRequest($phone, $templateCode, $templateParam, $signName, $region, $key_id, $key_secret,$app_id)
    {
        $host   = 'sms.tencentcloudapi.com';
        $phone = !is_array($phone)?[$phone]:$phone;
        $templateParam = !is_array($templateParam)?json_decode($templateParam,true): $templateParam;
        $newPhone = [];
        foreach ($phone as $key => $vo) {
            $vo = str_replace('+86','',$vo);
            $vo = str_replace('+','',$vo);
            $newPhone[] = '+86'.$vo;
        }
        $params = [
            'PhoneNumberSet'       => $newPhone,
            'SmsSdkAppId'       => $app_id,
            'TemplateId'      => $templateCode,
            'SignName' => $signName,
            'TemplateParamSet' => $templateParam
        ];
        $result = (new TencBase(['tenc_secret_key'=> $key_secret, 'tenc_secret_id'=> $key_id]))->curl_post($host, $params, 'SendSms', 'sms','2021-01-11', $region);
        // $result = $this->curl_post($host, $params, 'SendSms', 'sms','2021-01-11', $region, $key_id, $key_secret);
        $result = json_decode($result, true);
        $postData['send_result'] = true;
        $postData['send_error'] = '';
        $postData['send_result_data'] = json_encode($result);
        $postData['smsParam'] = json_encode($templateParam);
        if (isset($result['Response']['SendStatusSet'][0]['Code']) && strtolower($result['Response']['SendStatusSet'][0]['Code']) != 'ok') {
            $postData['send_result'] = false;
            $postData['send_error'] = $result['Response']['SendStatusSet'][0]['Code'] . '; [Message：' . $result['Response']['SendStatusSet'][0]['Message'] . ']';
        }
        return $postData;
    }
    public function curl_post($host, $params, $action, $service,$version, $region, $key_id, $key_secret)
    {
        $header = $this->makeHeader($host, $params, $action, $service,$version, $region, $key_id, $key_secret);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_URL, 'https://' . $host);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
        curl_setopt(
            $ch,
            CURLOPT_USERAGENT,
            'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
        );
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $output = curl_exec($ch);
        curl_close($ch);
        return $output;
    }
    private function makeHeader($host, $params, $action, $service,$version, $region, $key_id, $key_secret)
    {
        $headers = [
            'X-TC-Action'    => $action,
            'X-TC-Timestamp' => time(),
            'X-TC-Version'   => $version,
            'X-TC-Region'   => $region,
            'Content-Type'   => 'application/json',
            'Host'           => $host
        ];
        $algo         = "TC3-HMAC-SHA256";
        $date         = gmdate("Y-m-d", $headers["X-TC-Timestamp"]);
        $canonicalUri = '/';
        $reqMethod    = 'POST';

        $canonicalQueryString = '';
        $canonicalHeaders     = "content-type:" . $headers["Content-Type"] . "\n" . "host:" . $headers["Host"] . "\n";
        $signedHeaders        = "content-type;host";
        $payloadHash          = hash("SHA256", json_encode($params));
        $canonicalRequest     = $reqMethod . "\n" . $canonicalUri . "\n" . $canonicalQueryString . "\n" . $canonicalHeaders . "\n" . $signedHeaders . "\n" . $payloadHash;

        $credentialScope        = $date . "/" . $service . "/tc3_request";
        $hashedCanonicalRequest = hash("SHA256", $canonicalRequest);
        $str2sign               = $algo . "\n" . $headers["X-TC-Timestamp"] . "\n" . $credentialScope . "\n" . $hashedCanonicalRequest;
        $signature              = self::signTC3($key_id, $date, $service, $str2sign);

        $auth                     = $algo . " Credential=" . $key_secret . "/" . $credentialScope . ", SignedHeaders=content-type;host, Signature=" . $signature;
        $headers["Authorization"] = $auth;

        $temp = [];
        foreach ($headers as $key => $value) {
            array_push($temp, $key . ':' . $value);
        }
        return $temp;
    }
    protected static function signTC3($skey, $date, $service, $str2sign)
    {
        $dateKey    = hash_hmac("SHA256", $date, "TC3" . $skey, true);
        $serviceKey = hash_hmac("SHA256", $service, $dateKey, true);
        $reqKey     = hash_hmac("SHA256", "tc3_request", $serviceKey, true);

        return hash_hmac("SHA256", $str2sign, $reqKey);
    }
}
